package com.novel.base.handler;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.SaTokenException;
import com.novel.base.entity.R;
import com.novel.base.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

/**
 * GlobalExceptionHandler
 * 全局异常处理器
 *
 * @author 樊温军
 * @date 2025/3/22 上午11:23
 */
@Slf4j
@Order(10000)
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public R<Object> handleCustomException(CustomException ex) {
        return R.failed(ex);
    }

    @ExceptionHandler(SaTokenException.class)
    public R<Object> handlerSaTokenException(SaTokenException ex) {
        // 打印堆栈，以供调试
        log.error("全局异常SaTokenException：", ex);
        if (ex.getCode() == 20001) {
            return R.failed("redirect 重定向 url 是一个无效地址");
        }
        if (ex.getCode() == 20002) {
            return R.failed("redirect 重定向 url 不在 allowUrl 允许的范围内");
        }
        if (ex.getCode() == 20004) {
            return R.failed("提供的 ticket 是无效的");
        }
        return R.failed("服务器繁忙，请稍后重试...");
    }

    // 全局异常拦截（拦截项目中的NotLoginException异常）
    @ExceptionHandler(NotLoginException.class)
    public R<Object> handlerNotLoginException(NotLoginException ex) {
        // 打印堆栈，以供调试
        log.error("全局异常NotLoginException：", ex);
        // 判断场景值，定制化异常信息
        String message = "";
        if (ex.getType().equals(NotLoginException.NOT_TOKEN)) {
            message = "未提供token";
        } else if (ex.getType().equals(NotLoginException.INVALID_TOKEN)) {
            message = "token无效";
        } else if (ex.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
            message = "token已过期";
        } else if (ex.getType().equals(NotLoginException.BE_REPLACED)) {
            message = "token已被顶下线";
        } else if (ex.getType().equals(NotLoginException.KICK_OUT)) {
            message = "token已被踢下线";
        } else {
            message = "当前会话未登录";
        }
        // 返回给前端
        return R.failed(message);
    }

}
